home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / util1 / yk211src.lha / Yak_2.11_Src / WBStartup / Patch_libs.c < prev    next >
C/C++ Source or Header  |  1995-10-18  |  5KB  |  170 lines

  1. /*
  2. ** Contains all necessary functions to patch libraries functions safely.
  3. ** Theses functions are largely inspired from ISpy.c which can be found in
  4. ** the Amiga Mail archive (available from Fred Fish collection).
  5. **
  6. ** Author: Gael Marziou
  7. ** Created: 14 July 1994 (Bastille Day ;-)
  8. **
  9. */
  10.  
  11. #include "code.h"
  12. #include "Patch_Libs.h"
  13.  
  14.  
  15. struct JumpTable *
  16. GetJumpTable(UBYTE *name, struct LVOTable *LVOArray, UBYTE NumberOfFunctions)
  17. {
  18.     struct JumpTable *jumptable;
  19.     ULONG *addressptr;
  20.     UWORD *jmpinstr;
  21.     UBYTE *jtname;
  22.     UCOUNT i, j;
  23.  
  24.     /* Not really necessary to forbid again, just to indicate that I don't
  25.      * want another task to create the semaphore while I'm trying to do the
  26.      * same. Here GetJumpTable() is only called from InstallWedge(), so it
  27.      * will just bump the forbid count.
  28.      */
  29.     Forbid();
  30.  
  31.     if (!(jumptable = (struct JumpTable *) FindSemaphore(name)))
  32.     {
  33.         /* No jump table we have to allocate it */
  34.  
  35.         if (jumptable = AllocMem(sizeof(struct JumpTable) + ((NumberOfFunctions-1) * 6), 
  36.                                  MEMF_PUBLIC | MEMF_CLEAR))
  37.         {
  38.             if (jtname = AllocMem(strlen(name) + 1, MEMF_PUBLIC | MEMF_CLEAR))
  39.             {
  40.  
  41.                 for (i = 0, j = 0; i < NumberOfFunctions * 6; i += 6, j++)
  42.                 {
  43.                     jmpinstr = (UWORD *) ((UBYTE *) jumptable->jt_Function + i);
  44.                     *jmpinstr = 0x4EF9;
  45.  
  46.                     addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i + 2);
  47.                     *addressptr = (ULONG) SetFunction(
  48.                                                       (struct Library *) (*((ULONG *) LVOArray[j].lt_LibBase)),
  49.                                                       LVOArray[j].lt_LVO,
  50.                                                       (VOID *) ((UBYTE *) jumptable->jt_Function + i));
  51.                 }
  52.  
  53.                 jumptable->jt_Semaphore.ss_Link.ln_Pri = 0;
  54.  
  55.                 strcpy(jtname, name);
  56.                 jumptable->jt_Semaphore.ss_Link.ln_Name = jtname;
  57.                 AddSemaphore((struct SignalSemaphore *) jumptable);
  58.             } 
  59.             else
  60.             {
  61.                 FreeMem(jumptable, sizeof(struct JumpTable) + ((NumberOfFunctions-1) * 6));
  62.                 jumptable = NULL;
  63.             }
  64.         }
  65.     }
  66.     /* Clear the cpu's cache so the execution cache is valid */
  67.     CacheClearU();
  68.  
  69.     Permit();
  70.  
  71.     /* If succeeded, you now have a jumptable which entries point to the original
  72.      * library functions. If another task SetFunction()'ed one or more of those
  73.      * already, that task can never go away anymore.
  74.      */
  75.     return (jumptable);
  76. }
  77.  
  78.  
  79.  
  80. BOOL
  81. InstallWedge(UBYTE *JTName, struct LVOTable *LVOArray, UBYTE NumberOfFunctions)
  82. {
  83.     struct JumpTable *jumptable;
  84.     ULONG *addressptr;
  85.     UCOUNT i, j;
  86.  
  87.     Forbid();
  88.  
  89.     /* Get pointer to JumpTable. Create it if necessary */
  90.     if (jumptable = GetJumpTable(JTName, LVOArray, NumberOfFunctions))
  91.     {
  92.         /* Try to get exclusive lock on semaphore, in case it already existed. */
  93.         if (AttemptSemaphore((struct SignalSemaphore *) jumptable))
  94.         {
  95.             /* Make sure nobody else has function addresses in the jumptable */
  96.             if (jumptable->jt_Owner == NULL)
  97.             {
  98.                 jumptable->jt_Owner = FindTask(0);
  99.                 /* Don't want to disable any longer than necessary */
  100.                 Disable();
  101.  
  102.                 for (i = 2, j = 0; i < NumberOfFunctions * 6; i += 6, j++)
  103.                 {
  104.                     /* Replace addresses in the jumptable with my own. */
  105.                     addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
  106.                     (*((ULONG *) LVOArray[j].lt_oldFunction)) = (ULONG) * addressptr;
  107.                     *addressptr = (ULONG) LVOArray[j].lt_newFunction;
  108.                 }
  109.                 Enable();
  110.             } 
  111.             ReleaseSemaphore((struct SignalSemaphore *) jumptable);
  112.         } 
  113.     }
  114.     /* Clear the cpu's cache so the execution cache is valid */
  115.     CacheClearU();
  116.  
  117.     Permit();
  118.     return ((BOOL) jumptable);
  119. }
  120.  
  121.  
  122.  
  123. BOOL
  124. RemoveWedge(UBYTE *JTName, struct LVOTable *LVOArray, UBYTE NumberOfFunctions)
  125. {
  126.     struct JumpTable *jumptable;
  127.     ULONG *addressptr;
  128.     UCOUNT i, j;
  129.  
  130.     Forbid();
  131.  
  132.     if (jumptable = GetJumpTable(JTName, LVOArray, NumberOfFunctions))
  133.     {
  134.         /* Check if this task owns this jumptable */
  135.         if (jumptable->jt_Owner == FindTask(0))
  136.         {
  137.  
  138.             /* Get the semaphore exclusively.
  139.              * Depending on what got SetFunction()'ed this could take some time.
  140.              * Also note that shared locks are used to indicate the code is
  141.              * being executed and that shared locks can jump ahead of queue'ed
  142.              * exclusive locks, adding to the waittime.
  143.              */
  144.  
  145.             ObtainSemaphore((struct SignalSemaphore *) jumptable);
  146.  
  147.             Disable();
  148.  
  149.             /* Restore old pointers in jumptable */
  150.  
  151.             for (i = 2, j = 0; i < NumberOfFunctions * 6; i += 6, j++)
  152.             {
  153.                 addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
  154.                 *addressptr = (*((ULONG *) LVOArray[j].lt_oldFunction));
  155.             }
  156.  
  157.             Enable();
  158.             jumptable->jt_Owner = NULL;
  159.             ReleaseSemaphore((struct SignalSemaphore *) jumptable);
  160.         }
  161.     }
  162.     /* Clear the cpu's cache so the execution cache is valid */
  163.     CacheClearU();
  164.  
  165.     Permit();
  166.  
  167.     return (TRUE);
  168. }
  169.  
  170.